<!-- @format -->

<template>
  <div
    class="comp-button"
    :class="[
      `comp-button--${theme}`,
      `comp-button--${size}`,
      { 'comp-button--disabled': disabled || loading },
      { 'comp-button--loading': loading },
      { 'comp-button--focus': isFocused },
      { 'comp-button--block': block }
    ]"
    :disabled="disabled || loading"
    :type="type"
    :role="role"
    :aria-label="ariaLabel"
    :aria-disabled="disabled || loading"
    :tabindex="disabled ? -1 : 0"
    @click="handleClick"
    @focus="handleFocus"
    @blur="handleBlur"
    @keydown.enter="handleKeyDown"
    @keydown.space="handleKeyDown"
  >
    <!-- 加载图标 -->
    <div v-if="loading" class="comp-button__loading">
      <div class="comp-button__loading-spinner"></div>
    </div>

    <!-- 左侧图标 -->
    <div v-if="icon && iconPosition === 'left'" class="comp-button__icon comp-button__icon--left">
      <slot name="icon">
        <span class="comp-button__icon-inner">{{ icon }}</span>
      </slot>
    </div>

    <!-- 按钮内容 -->
    <div class="comp-button__content">
      <slot>{{ text }}</slot>
    </div>

    <!-- 右侧图标 -->
    <div v-if="icon && iconPosition === 'right'" class="comp-button__icon comp-button__icon--right">
      <slot name="icon">
        <span class="comp-button__icon-inner">{{ icon }}</span>
      </slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

// 定义按钮属性
interface Props {
  /** 按钮类型 */
  type?: 'button' | 'submit' | 'reset'
  /** 按钮主题 */
  theme?: 'primary' | 'secondary' | 'danger' | 'success' | 'default'
  /** 按钮尺寸 */
  size?: 'small' | 'medium' | 'large'
  /** 是否禁用 */
  disabled?: boolean
  /** 是否加载中 */
  loading?: boolean
  /** 按钮文本 */
  text?: string
  /** 图标 */
  icon?: string
  /** 图标位置 */
  iconPosition?: 'left' | 'right'
  /** 是否块级按钮（宽度100%） */
  block?: boolean
  /** 无障碍标签 */
  ariaLabel?: string
  /** 角色 */
  role?: string
}

// 定义默认属性
const props = withDefaults(defineProps<Props>(), {
  type: 'button',
  theme: 'default',
  size: 'medium',
  disabled: false,
  loading: false,
  text: '',
  icon: '',
  iconPosition: 'left',
  block: false,
  ariaLabel: '',
  role: 'button'
})

// 定义事件
const emit = defineEmits<{
  /** 点击事件 */
  (e: 'click', event: MouseEvent): void
  /** 获得焦点事件 */
  (e: 'focus', event: FocusEvent): void
  /** 失去焦点事件 */
  (e: 'blur', event: FocusEvent): void
}>()

// 焦点状态
const isFocused = ref(false)

// 处理点击事件
const handleClick = (event: MouseEvent) => {
  if (props.disabled || props.loading) return
  emit('click', event)
}

// 处理键盘事件
const handleKeyDown = (event: KeyboardEvent) => {
  if (props.disabled || props.loading) return
  if (event.key === 'Enter' || event.key === ' ') {
    event.preventDefault()
    const clickEvent = new MouseEvent('click', {
      bubbles: true,
      cancelable: true,
      view: window
    })
    event.target?.dispatchEvent(clickEvent)
  }
}

// 处理焦点事件
const handleFocus = (event: FocusEvent) => {
  isFocused.value = true
  emit('focus', event)
}

// 处理失焦事件
const handleBlur = (event: FocusEvent) => {
  isFocused.value = false
  emit('blur', event)
}

// 暴露方法
defineExpose({
  focus: () => {
    const el = document.querySelector('.comp-button') as HTMLElement
    el?.focus()
  },
  blur: () => {
    const el = document.querySelector('.comp-button') as HTMLElement
    el?.blur()
  }
})
</script>

<style scoped>
.comp-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-weight: 500;
  transition: all 0.2s ease;
  position: relative;
  overflow: hidden;
  outline: none;
  user-select: none;
}

/* 尺寸 */
.comp-button--small {
  height: 32px;
  padding: 0 12px;
  font-size: 12px;
}

.comp-button--medium {
  height: 40px;
  padding: 0 16px;
  font-size: 14px;
}

.comp-button--large {
  height: 48px;
  padding: 0 20px;
  font-size: 16px;
}

/* 主题 */
.comp-button--default {
  background-color: #f5f5f5;
  color: #333;
}

.comp-button--default:hover {
  background-color: #e8e8e8;
}

.comp-button--primary {
  background-color: #007aff;
  color: white;
}

.comp-button--primary:hover {
  background-color: #0062cc;
}

.comp-button--secondary {
  background-color: #6c757d;
  color: white;
}

.comp-button--secondary:hover {
  background-color: #5a6268;
}

.comp-button--danger {
  background-color: #dc3545;
  color: white;
}

.comp-button--danger:hover {
  background-color: #c82333;
}

.comp-button--success {
  background-color: #28a745;
  color: white;
}

.comp-button--success:hover {
  background-color: #218838;
}

/* 禁用状态 */
.comp-button--disabled {
  opacity: 0.65;
  cursor: not-allowed;
  pointer-events: none;
}

/* 加载状态 */
.comp-button--loading {
  cursor: wait;
}

.comp-button__loading {
  margin-right: 8px;
}

.comp-button__loading-spinner {
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: #fff;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* 焦点状态 */
.comp-button--focus {
  box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}

/* 块级按钮 */
.comp-button--block {
  display: flex;
  width: 100%;
}

/* 图标 */
.comp-button__icon {
  display: flex;
  align-items: center;
}

.comp-button__icon--left {
  margin-right: 8px;
}

.comp-button__icon--right {
  margin-left: 8px;
}

.comp-button__content {
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
